<?php

namespace App\Services;

use App\Events\OrderPaySuccess;
use App\Models\Order;
use App\Models\OrderChangeLog;
use App\Models\User;
use Illuminate\Support\Facades\DB;

/**
 * 订单服务
 * Class OrderService
 * @package App\Services
 */
class OrderService extends BaseService
{
    /**
     * 余额支付
     * @param $orderInfo
     * @param string $attach
     * @return mixed
     * @throws \Throwable
     */
    public static function yuePay($orderInfo, $attach = 'legwork')
    {
        $user = User::find($orderInfo['uid']);
        if (!$user) {
            return self::ierror(-1, '订单用户不存在');
        }

        $totalBalance = $user->balance;

        if ($totalBalance < $orderInfo['pay_price']) {
            return self::ierror(-1, '余额不足');
        }
        if ($orderInfo['paid']) {
            return self::ierror(-1, '该订单已支付');
        }
        //优先扣除赠送余额

        $useGiveBalance = 0;

        $user->balance = $user->balance - $orderInfo['pay_price'];
        $useBalance = $orderInfo['pay_price'];


        $ret = $user->saveOrFail();
        if (!$ret) {
            DB::rollBack();
            return self::ierror(-1, '用户余额扣除失败');
        }
        //余额明细
        BalanceService::addCreditLog(10, $user->id, 1, -$useBalance, $user->balance, '', -$useGiveBalance, 0, 0, $user->give_balance, $orderInfo->id);
        try {
            $result = self::paySuccessOrder($orderInfo, 'yue');

            $data = [
                'status' => 'SUCCESS',
                'result' => $result,
            ];
            return  $data;

        } catch (\Exception $exception) {
            DB::rollBack();
            return self::ierror(-1, $exception->getMessage());
        }

    }

    /**
     * 微信支付为0元时
     * @param $orderId
     * @param $uid
     * @param $pay_type
     * @param $attach
     * @return bool
     * @throws
     */
    public static function jsPayPrice($orderId, $uid, $pay_type, $attach = 'legwork')
    {

        $orderInfo = Order::getByOrderId($orderId);

        if (!$orderInfo) {
            return self::ierror(-1, '订单不存在!');
        }
        if ($orderInfo['uid'] != $uid) {
            return self::ierror(-1, '非法订单!');
        }
        if ($orderInfo['paid']) {
            return self::ierror(-1, '订单已支付!');
        }

        $userInfo = User::find($uid);
        if (!$userInfo) {
            return self::ierror(-1, '购买用户已被删除!');
        }

        $res = self::paySuccessOrder($orderInfo, $pay_type, $attach);

        return $res;
    }

    /**
     * 订单支付成功调用
     * @param Order $orderInfo
     * @param string $paytype
     * @param string $attach
     * @param string $transactionId
     * @return boolean
     * @throws \Exception
     */
    public static function paySuccessOrder($orderInfo, $paytype = 'yue', $attach = 'legwork', $transactionId = '')
    {
        //更新订单状态
        $data = [
            'paid' => 1,
            'transaction_id' => (string)$transactionId,
            'pay_time' => time(),
            'status' => 1
        ];

        $ret = $orderInfo->fill($data)->save();
        if (!$ret) {
            exception('订单支付状态更新失败' . $orderInfo->id);
        }
        //支付成功事件
        event(new OrderPaySuccess($orderInfo, $attach, $paytype));
        return true;
    }

    /**
     * 生成唯一订单号
     * @return string
     */
    public static function getNewOrderId()
    {

        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);


        $orderId = 'RCH' . $msectime . mt_rand(10000, 99999);

        if (Order::whereOrderId($orderId)->exists()) {
            $orderId = 'RCH' . $msectime . mt_rand(10000, 99999);
        }

        return $orderId;
    }

    /**
     * 订单操作日志记录
     * @param $oid
     * @param $type
     * @param $message
     * @return bool
     */
    public static function log($oid, $type, $message)
    {
        $log = new OrderChangeLog();

        $data = [
            'oid' => $oid,
            'change_type' => $type,
            'change_message' => $message,
        ];

        return $log->fill($data)->save($data);
    }
}